package com.hutu.core.serial;

import com.hutu.core.redis.IRedisService;
import com.hutu.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class IdNoUtil {

    static IRedisService cacheService = (IRedisService) SpringUtil.getBean("redisServiceImpl");


    /**
     * 运次序列
     * @return
     */
    public static String generateCycleNo(){
        return generateSerialNo("TL");
    }

    /**
     * 运单序列
     * @return
     */
    public static String generateWayBillNo(){
        return generateSerialNo("FL");
    }

    /**
     * 生成17位唯一流水号，prefix+yyyyMMdd+4位数字
     * 4位数字，如：0001
     * @return
     */
    public static String generateSerialNo(String prefix){
        //定义需要返回的流水号
        String serialNo = null;
        //先查询到今天的日期，格式:"yyyyMMdd"
        String todayDate = new SimpleDateFormat("yyyyMMdd")
                .format(new Date());
        //固定字母前缀 拼接 今天日期，组成新的完整的前缀，也就是缓存的key
        String cacheKey = prefix + todayDate;
        //再通过key查询缓存有没有num数据，缓存操作根据自身项目封装工具类
        Long codeNum = cacheService.getIncr(cacheKey,getSeconds());
        //流水号 = 缓存key + 拼接的数值 = 前缀 + 日期 + 拼接的数值
        serialNo = getCodeOfSix(cacheKey, codeNum.intValue());
        log.info(String.format("流水号：%s",serialNo));
        return serialNo;
    }

    /**
     * 将数值拼接成对应的位数
     * @param prefix  前缀 + yyyyMMdd
     * @param nowNum  当前要生成的数字
     * @return 拼接好的流水号
     */
    public static String getCodeOfSix(String prefix,int nowNum ) {
        //需要返回的code
        StringBuilder codeSb = new StringBuilder();
        //需要拼接的数字
        StringBuilder numSb = new StringBuilder();
        //封装的数字对象，里面 value 加了 volatile关键字，保证了线程安全
        AtomicInteger count = new AtomicInteger(nowNum);

        //将数值补足为4位字符串
        if (count.get() < 10) {
            numSb.append("000").append(count.get());
        } else if(count.get() < 100){
            numSb.append("00").append(count.get());
        }else if(count.get() < 1000){
            numSb.append("0").append(count.get());
        }else if (count.get() >= 1000) {
            numSb.append(count.get());
        }

        //先拼接前缀
        codeSb.append(prefix);
        //再拼接数字
        codeSb.append(numSb);
        return codeSb.toString();
    }

    /**
     * 获取当天结束还剩余多少秒
     * @return
     */
    public static int getSeconds(){
        //获取今天当前时间
        Calendar curDate = Calendar.getInstance();
        //获取明天凌晨0点的日期
        Calendar tommorowDate = new GregorianCalendar(
                curDate.get(Calendar.YEAR),
                curDate.get(Calendar.MONTH),
                curDate.get(Calendar.DATE) + 1,
                0, 0, 0);
        //返回 明天凌晨0点 和 今天当前时间 的差值（秒数）
        return (int)(tommorowDate.getTimeInMillis() - curDate .getTimeInMillis()) / 1000;
    }
}
